<?php

// $Id$


require_once(TANGRA_MAIN_DIR.'interfaces/i_db_storable.class.php');


require_once('tcms_category.class.php');


class TCMS_Category_DBC extends TCMS_Category implements I_DB_Storable {
	public function save(DB_Connection $dbc) {
		$ret = false;

		if ($this->get_id()) {
			$ret = $this->update($dbc);
		} else {
			$ret = $this->insert($dbc);
			$this->set_id($ret);

		}

		if ($ret) {
			$subcategories = $this->get_subcategories();

			foreach($subcategories as $subcategory) {
				$subcategory->set_parent($ret);
				$subcategory->save($dbc);
			}
		}

		return $ret;
	}


	public function load_by_id(DB_Connection $dbc, $id) {
		tangra_if_not_int_throw_e($id);

		$ret = $this->_load_by_id($dbc, $id);

		$sql = "select id from tcms_categories where parent = $id order by `ordering` asc";
		$rez = $dbc->execute($sql);
		while($rez_obj = $rez->fetch_object()) {
			$category = new TCMS_Category_DBC();
			$category->load_by_id($dbc, $rez_obj->ID);

			$this->add_subcategory(clone $category);
		}


		return $ret;
	}


	public function load_by_hid(DB_Connection $dbc, $hid) {
		$ret= false;

		$hid = addslashes($hid);
		$sql = "select id from tcms_categories where hid = '$hid'";

		$rez = $dbc->execute($sql);
		if (!$rez->is_eod()) {
			$rez_obj = $rez->fetch_object();
			$ret = $this->load_by_id($dbc, $rez_obj->ID);
		}

		return $ret;
	}


	protected function _load_by_id(DB_Connection $dbc, $id) {
		$ret = false;

		$sql = "select hid, "
						." title,"
						." parent,"
						." ordering, "
						." last_modified"
					." from tcms_categories "
					."where id = $id";
		$rez = $dbc->execute($sql);

		if (!$rez->is_eof()) {
			$rez_obj = $rez->fetch_object();

			$this->set_id($id);
			$this->set_hid($rez_obj->HID);
			$this->set_title(stripslashes($rez_obj->TITLE));
			$this->set_parent($rez_obj->PARENT);
			$this->set_ordering($rez_obj->ORDERING);
			$this->set_last_modified($rez_obj->LAST_MODIFIED);

			$ret = $id;
		}

		return $ret;
	}


	protected function insert(DB_Connection $dbc) {
		$ret = false;

		$id = $dbc->generate_id('tcms_categories_seq');

		$hid = $this->get_hid();
		$title = addslashes($this->get_title());
		$parent = $this->get_parent();
		$ordering = $this->get_ordering();
		$last_modified = date('Y-m-d H:i:s');

		if ($id) {
			$sql = "insert into tcms_categories (id, "
											."hid, "
											."title, "
											."parent, "
											."ordering, "
											."last_modified "
									      .") ".
								"values ".
									      "($id,".
									      "'$hid', ".
									      "'$title', ".
									      "$parent, ".
									      "$ordering, ".
									      "'$last_modified'".
									      ")";
			$dbc->execute($sql);
			$ret = $id;

			if ($parent) {
				self::update_last_modified($dbc, $parent);
			}
		} else {
			throw new TE_Exception('ID not generated - tcms_categories_seq');
		}


		return $ret;
	}


	protected function update(DB_Connection $dbc) {
		$id = $this->get_id();

		$hid = $this->get_hid();
		$title = addslashes($this->get_title());
		$parent = $this->get_parent();
		$ordering = $this->get_ordering();
		$last_modified = date('Y-m-d H:i:s');

		$sql = "update tcms_categories set ".
							      "hid = '$hid', ".
							      "title = '$title', ".
							      "parent = $parent, ".
							      "ordering = $ordering, ".
							      "last_modified = '$last_modified' ".
					"where id = ".$id;

		$dbc->execute($sql);
		$ret = $id;

		if ($parent) {
			self::update_last_modified($dbc, $parent);
		}

		return $ret;
	}


	public function add_subcategory(TCMS_Category $category) {
		if ($category instanceof TCMS_Category_DBC) {
			parent::add_subcategory($category);
		} else {
			throw new TE_TCMS_Exception('$category is not instance of TCMS_Category_DBC');
		}
	}


	public function update_subcategory(TCMS_Category $category) {
		if ($this->subcategory_exists($category)) {
			$category_orig = $this->subcategories[$item->get_hid()];
			$id = $category_orig->get_id();
			$subitems = $category_orig->get_subcategories();

			$category->set_id($id);
			$category->set_subcategories($subitems);
			$this->subcategories[$category->get_hid()] = $category;
		} else {
			throw new TE_TCMS_Exception('Such subcategory does not exists: '.$category->get_hid());
		}
	}


	public static function delete(DB_Connection $dbc, $id) {
		tangra_if_not_int_throw_e($id);

		$sql = "delete from tcms_categories where id = $id";

		$dbc->execute($sql);
	}


	public static function move_up(DB_Connection $dbc, $id) {
		$current = new TCMS_Category_DBC();

		if ($current->load_by_id($dbc, $id)) {
			$sql = "select id from tcms_categories where "
						."parent = ".$current->get_parent()
						." and `ordering` <= ".$current->get_ordering()
						." and id <> $id "
						." order by `ordering` desc";
			$rez = $dbc->execute($sql);

			if (!$rez->is_eod()) {
				$above = new TCMS_Category_DBC();
				$rez_obj = $rez->fetch_object();
				$above->load_by_id($dbc, $rez_obj->ID);

				if ($current->get_ordering() != $above->get_ordering()) {
					// Swaping orders
					$tmp = $current->get_ordering();
					$current->set_ordering($above->get_ordering());
					$above->set_ordering($tmp);
				} else {
					if (($above->get_ordering() - 10) > 0) {
						$current->set_ordering($above->get_ordering() - 10);
					} else {
						$above->set_ordering($above->get_ordering() + 10);
					}
				}

				$current->save($dbc);
				$above->save($dbc);
			}
		}
	}


	public static function move_down(DB_Connection $dbc, $id) {

		$current = new TCMS_Category_DBC();

		if ($current->load_by_id($dbc, $id)) {
			$sql = "select id from tcms_categories where "
						."parent = ".$current->get_parent()
						." and `ordering` >= ".$current->get_ordering()
						." and id <> $id "
						." order by `ordering` asc";
			$rez = $dbc->execute($sql);
			if (!$rez->is_eod()) {
				$bellow = new TCMS_Category_DBC();
				$rez_obj = $rez->fetch_object();
				$bellow->load_by_id($dbc, $rez_obj->ID);

				if ($current->get_ordering() != $bellow->get_ordering()) {
					// Swaping orders
					$tmp = $current->get_ordering();
					$current->set_ordering($bellow->get_ordering());
					$bellow->set_ordering($tmp);
				} else {
					$current->set_ordering($bellow->get_ordering() + 10);
				}

				$current->save($dbc);
				$bellow->save($dbc);
			}
		}
	}


	public static function is_unique_hid(DB_Connection $dbc, $hid) {
		$hid = addslashes($hid);

		$sql = "select id from tcms_categories where hid = '$hid'";
		$rez = $dbc->execute($sql);

		return $rez->is_eod();
	}


	public static function is_unique_hid_update(DB_Connection $dbc, $hid, $id) {
		tangra_if_not_int_throw_e($id);
		$hid = addslashes($hid);

		$sql = "select id from tcms_categories where hid = '$hid' and id <> $id";
		$rez = $dbc->execute($sql);

		return $rez->is_eod();
	}


	public static function load_categories_by_parent(DB_Connection $dbc, $parent) {
		tangra_if_not_int_throw_e($parent);

		$ret = array();
		$sql = "select id from tcms_categories where parent = $parent order by `ordering`";
		$rez = $dbc->execute($sql);
		while($rez_obj = $rez->fetch_object()) {
			$tmp = new TCMS_Category_DBC();
			$tmp->load_by_id($dbc, $rez_obj->ID);

			$ret[] = clone $tmp;
		}

		return $ret;
	}


	public static function category_exists(DB_Connection $dbc, $id) {
		tangra_if_not_int_throw_e($id);
		$sql = "select id from tcms_categories where id = $id";
		$rez = $dbc->execute($sql);

		return !$rez->is_eod();
	}


	public static function get_next_order(DB_Connection $dbc, $parent_id) {
		tangra_if_not_int_throw_e($parent_id);

		$ret = 10;

		$sql = "select ordering from tcms_categories where parent = $parent_id order by ordering desc";
		$rez = $dbc->execute($sql);
		if (!$rez->is_eod()) {
			$rez_obj = $rez->fetch_object();
			$ret = ((int)($rez_obj->ORDERING / 10) + 1)*10; //next ordering calculation
		}

		return $ret;
	}


	public static function select_childs_ids(DB_Connection $dbc, $parent_id) {
		tangra_if_not_int_throw_e($parent_id);

		$ret = array();

		$sql = "select id from tcms_categories where parent = $parent_id";
		$rez = $dbc->execute($sql);
		while ($rez_obj = $rez->fetch_object()) {
			$ret[] = $rez_obj->ID;
		}

		return $ret;
	}


	public static function update_last_modified(DB_Connection $dbc, $cat_id) {
		tangra_if_not_int_throw_e($cat_id);
		$dt = date('Y-m-d H:i:s');
		$sql = "update tcms_categories set last_modified = '$dt' where id = $cat_id";
		$dbc->execute($sql);
	}


	public static function load_categories_ol_map(DB_Connection $dbc, $parent = 0, $level = 0) {
		tangra_if_not_int_throw_e($parent);
		$sql = "select id, title from tcms_categories where parent = $parent order by title asc";
		$rez = $dbc->execute($sql);

		$ret = array();
		$ids = array();

		while($rez_obj = $rez->fetch_object()) {
			array_push($ids, $rez_obj->ID);

			$ret['ol_map'][$rez_obj->ID] = str_repeat('&nbsp;', $level*4).$rez_obj->TITLE;
			$childs = self::load_categories_ol_map($dbc, $rez_obj->ID, $level + 1);
			if (array_key_exists('ids', $childs)) {
				$ids = array_merge($ids, $childs['ids']);
				foreach($childs['ol_map'] as $key => $value) {
					$ret['ol_map'][$key] = $value;
				}
			}
		}

		if ($ids) {
			$ret['ids'] = $ids;
		}


		return $ret;
	}
}